var AdminServerHandler=Java.extend(ChannelHandlerAdapter, {
	isSharable:function() {return true},
	channelActive:function( ctx) {
		handleAdmConnect(ctx);
	},
	
	channelRead:function(ctx, msg) {
		var cmdLine = msg;
		handleAdmCmd(cmdLine, ctx);
	},
	
	exceptionCaught:function(ctx, e) {
		logger.debug("", e.getCause());
		//ctx.close();
	},

});
var adminServerHandler=new AdminServerHandler();

var RpggameServerHandler=Java.extend(ChannelHandlerAdapter, {
	isSharable:function() {return true},
	channelRead:function( ctx, msg) {
		var byteBuf = msg;
		readLength(byteBuf);//field length
		clientCmdHandler(byteBuf, ctx);
	},

	exceptionCaught:function(ctx, e) {
		logger.debug(e.getMessage(), e.getCause());
		removeClient(ctx.channel());
		ctx.close();
	},
});
var rpggameServerHandler=new RpggameServerHandler();

var lengthFieldBasedFrameDecoder=new (Java.type("io.netty.handler.codec.LengthFieldBasedFrameDecoder"))(MaxFrameLength, 0, LengthFieldLength);
var lengthFieldPrepender=new (Java.type("io.netty.handler.codec.LengthFieldPrepender"))(LengthFieldLength)
var stringDecoder=new (Java.type("io.netty.handler.codec.string.StringDecoder"))(charset);
var stringEncoder=new (Java.type("io.netty.handler.codec.string.StringEncoder"))(charset);

var ServerBootstrap=Java.type("io.netty.bootstrap.ServerBootstrap");
var ChannelInitializer=Java.type("io.netty.channel.ChannelInitializer");
var ChannelOption=Java.type("io.netty.channel.ChannelOption");
var ChannelFuture=Java.type("io.netty.channel.ChannelFuture");
var NioServerSocketChannel=Java.type("io.netty.channel.socket.nio.NioServerSocketChannel");
var SocketChannel= Java.type("io.netty.channel.socket.SocketChannel");

function startServer(serverPort, h1,h2,h3,//
        bossGroup, workerGroup){
    var b = new ServerBootstrap();
    b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
    .childHandler(new ChannelInitializer(){
        initChannel:function(ch) {
            ch.pipeline().addLast(h1);
            ch.pipeline().addLast(h2);
            ch.pipeline().addLast(h3);
        }
    }).option(ChannelOption.SO_BACKLOG, 128)
    .childOption(ChannelOption.SO_KEEPALIVE, true);

    // Bind and start to accept incoming connections.
    return b.bind(serverPort).sync();

}

function shutdown() {
    logger.info("shutdonw");
}

java.lang.Runtime.getRuntime().addShutdownHook(new java.lang.Thread() {
            run:function() {
                shutdown();
            }
});

var NioEventLoopGroup=Java.type("io.netty.channel.nio.NioEventLoopGroup");
var clientServer=null;
var adminServer=null;

function start(){//
        var bossGroup = new NioEventLoopGroup();
        var workerGroup = new NioEventLoopGroup();
        try {
            clientServer = startServer(clientServerPort,lengthFieldBasedFrameDecoder ,lengthFieldPrepender,//
            		rpggameServerHandler,bossGroup, workerGroup);
            adminServer = startServer(adminServerPort, stringDecoder,stringEncoder,//
            		adminServerHandler,bossGroup, workerGroup);
            clientServer.channel().closeFuture().sync();
            adminServer.channel().closeFuture().sync();
        } catch (e) {
        	logger.error(e.message,e);
        	workerGroup.shutdownGracefully();
        	bossGroup.shutdownGracefully();
        } finally {
        }
}

start();

